package com.codrim.cs.data.server.subservice;

import com.codrim.cs.data.rpc.enums.TimeDimension;

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.springframework.util.Assert;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import lombok.experimental.UtilityClass;

/**
 * @author liang.ma on 04/12/2017.
 */
@UtilityClass
public class ReportUtils {

    /**
     * 获取制定时区的各个时间维度[日,周,月,年]
     *
     * @param yyyyMMddHH 指定时区的时间
     * @return List<Integer>
     */
    public static List<TimeDimensionWithSdate> toMultiTimeDimensionWithSdate(String yyyyMMddHH, int timeZone) {
        return Arrays.stream(TimeDimension.values())
                .map(item -> timeDimensionWithSdate(yyyyMMddHH, timeZone, item))
                .collect(Collectors.toList());
    }

    public static TimeDimensionWithSdate timeDimensionWithSdate(int intDate, int timeZone, TimeDimension timeDimension) {
        return timeDimensionWithSdate(String.valueOf(intDate), timeZone, timeDimension);
    }

    public static TimeDimensionWithSdate timeDimensionWithSdate(String intDate, int timeZone, TimeDimension timeDimension) {
        Assert.notNull(timeDimension, "timeDimension can not be null");
        Assert.isTrue(intDate.length() >= 4, "invalid param, length must >= 4");
        if (timeDimension == TimeDimension.Hour) {
            Assert.isTrue(intDate.length() == 10, "invalid param intDate, length must >= 10");
            return new TimeDimensionWithSdate(TimeDimension.Hour, Integer.valueOf(intDate));
        } else if (timeDimension == TimeDimension.Day) {
            Assert.isTrue(intDate.length() >= 8, "invalid param intDate, length must >= 8");
            return new TimeDimensionWithSdate(TimeDimension.Day, Integer.valueOf(intDate.substring(0, 8)));
        } else if (timeDimension == TimeDimension.Week) {
            DateTime dateTime =
                    DateTimeFormat.forPattern("yyyyMMddHH").withZone(DateTimeZone.UTC).parseDateTime(intDate).minusHours(timeZone);
            int weekOfYear = dateTime.getWeekOfWeekyear();
            String sYear = String.valueOf(dateTime.getYear());
            String weekOfYearS;
            if (weekOfYear < 10) {
                weekOfYearS = "0" + weekOfYear;
            } else {
                weekOfYearS = String.valueOf(weekOfYear);
            }
            return new TimeDimensionWithSdate(TimeDimension.Week, Integer.parseInt(sYear.concat(weekOfYearS)));
        } else if (timeDimension == TimeDimension.Month) {
            Assert.isTrue(intDate.length() >= 6, "invalid param intDate, length must >= 6");
            return new TimeDimensionWithSdate(TimeDimension.Month, Integer.valueOf(intDate.substring(0, 6)));
        } else {
            return new TimeDimensionWithSdate(TimeDimension.Year, Integer.valueOf(intDate.substring(0, 4)));
        }
    }

}
